
######################  OpenMP parallelization  ###########################

OMP_OPTS =  -fopenmp

######################        Compiler          ###########################

CC  = gcc -g -Wall -W -Wextra -Wlogical-op -Wstrict-prototypes -Wshadow -Wpointer-arith -Werror -Wcast-qual -Wcast-align -Wwrite-strings -Wnested-externs -Wfloat-conversion -fshort-enums -fno-common -Dinline= 

#########################    Architecture    ##############################

ARCH = -march=native

###############         Optimization flags        #########################

OPT = -O3 -ffast-math -ffinite-math-only -fprefetch-loop-arrays\
        -malign-double -funroll-all-loops \
        -mfpmath=sse -fassociative-math -ftree-vectorizer-verbose=0\
        -finline-functions -finline-limit=1000000

###########################################################################

LIB  = -lm
LIB_CUDA = -lcuda -lcudart -lstdc++

###########################################################################


%.o: %.c
	$(CC) -c $(ARCH) $(OMP_OPTS) $(OPT) $< -o $@

%.o: %.cu
	nvcc --ptxas-options=-v -forward-unknown-to-host-compiler -Xptxas -O3 --use_fast_math -extra-device-vectorization --restrict -res-usage --default-stream=per-thread  $(ARCH) $(OMP_OPTS) -Xcompiler $(OPT) -c $< -o $@

all: example-0-host example-0-gpu

example-0-host: example-0-host.o
	$(CC) $(OMP_OPTS) -o example-0-host example-0-host.o $(LIB)

example-0-gpu: example-0-gpu.o
	$(CC) $(OMP_OPTS) -o example-0-gpu example-0-gpu.o $(LIB) $(LIB_CUDA)

example-0-gpu1: example-0-gpu1.o
	$(CC) $(OMP_OPTS) -o example-0-gpu1 example-0-gpu1.o $(LIB) $(LIB_CUDA)

example-0-gpu2: example-0-gpu2.o
	$(CC) $(OMP_OPTS) -o example-0-gpu2 example-0-gpu2.o $(LIB) $(LIB_CUDA)

example-0-gpu2-streams: example-0-gpu2-streams.o
	$(CC) $(OMP_OPTS) -o example-0-gpu2-streams example-0-gpu2-streams.o $(LIB) $(LIB_CUDA)


clean:
	rm -f *.o example-0-host example-0-gpu example-0-gpu1 example-0-gpu2 example-0-gpu2-streams
